import requests
import pandas as pd
import time
import json
from datetime import datetime

# 设置请求头，模拟浏览器访问
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}


def get_fund_historical_data(fund_code, start_date=None, end_date=None):
    """
    获取基金历史净值数据
    :param fund_code: 基金代码（如 '001717'）
    :param start_date: 开始日期（格式：'YYYY-MM-DD'）
    :param end_date: 结束日期（格式：'YYYY-MM-DD'）
    :return: DataFrame 包含历史净值数据
    """
    # 天天基金历史净值接口
    url = f'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={fund_code}&page=1&per=1000'
    if start_date and end_date:
        url += f'&sdate={start_date}&edate={end_date}'

    response = requests.get(url, headers=headers)
    if response.status_code != 200:
        print(f"请求失败，状态码: {response.status_code}")
        return None

    # 解析返回的 HTML 数据
    content = response.text
    # 提取表格数据（需要根据实际接口返回格式解析）
    # 这里假设返回的是 JSON 或可直接解析的表格
    # 以下为简化示例，实际可能需要使用 BeautifulSoup 或正则表达式解析
    try:
        # 假设数据在 JSON 中
        data = pd.read_html(content, encoding='utf-8')[0]
        return data
    except Exception as e:
        print(f"解析历史数据失败: {e}")
        return None


def get_fund_realtime_data(fund_code):
    """
    获取基金实时估值数据
    :param fund_code: 基金代码（如 '001717'）
    :return: 字典包含实时估值数据
    """
    # 天天基金实时估值接口
    url = f'http://fundgz.1234567.com.cn/js/{fund_code}.js'
    response = requests.get(url, headers=headers)
    if response.status_code != 200:
        print(f"请求失败，状态码: {response.status_code}")
        return None

    # 解析返回的 JSONP 数据
    try:
        content = response.text
        # 去除 JSONP 的回调函数部分，提取 JSON 数据
        json_data = content[content.find('(') + 1:content.rfind(')')]
        data = json.loads(json_data)
        return {
            'fund_code': data.get('fundcode', ''),
            'name': data.get('name', ''),
            'gztime': data.get('gztime', ''),  # 估值时间
            'gz': data.get('gsz', ''),  # 估算净值
            'gz_rate': data.get('gszzl', '')  # 估算涨跌幅
        }
    except Exception as e:
        print(f"解析实时数据失败: {e}")
        return None


def main():
    # 示例基金代码
    fund_code = '001717'
    start_date = '2024-01-01'
    end_date = datetime.now().strftime('%Y-%m-%D')

    # 获取历史数据
    print(f"正在获取基金 {fund_code} 的历史数据...")
    historical_data = get_fund_historical_data(fund_code, start_date, end_date)
    if historical_data is not None:
        print("历史净值数据：")
        print(historical_data)
        # 保存到 CSV 文件
        historical_data.to_csv(f'{fund_code}_historical_data.csv', index=False)

    # 获取实时数据
    print(f"\n正在获取基金 {fund_code} 的实时估值数据...")
    realtime_data = get_fund_realtime_data(fund_code)
    if realtime_data is not None:
        print("实时估值数据：")
        for key, value in realtime_data.items():
            print(f"{key}: {value}")

    # 模拟实时数据轮询（每 60 秒获取一次）
    print("\n开始实时数据轮询（按 Ctrl+C 停止）...")
    try:
        while True:
            realtime_data = get_fund_realtime_data(fund_code)
            if realtime_data is not None:
                print(f"[{datetime.now()}] 实时估值: {realtime_data['gz']} ({realtime_data['gz_rate']}%)")
            time.sleep(60)  # 每 60 秒请求一次
    except KeyboardInterrupt:
        print("停止实时数据轮询")


if __name__ == "__main__":
    main()